package com.dynabook.ems.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dynabook.ems.common.BaseResponse;
import com.dynabook.ems.common.ErrorCode;
import com.dynabook.ems.common.ResultUtils;
import com.dynabook.ems.exception.BusinessException;
import com.dynabook.ems.mapper.EmsBomContactMapper;
import com.dynabook.ems.mapper.EmsBomDetailMapper;
import com.dynabook.ems.model.dto.WorkOrderBomDetailRequest;
import com.dynabook.ems.model.dto.WorkOrderBomSimpleRequest;
import com.dynabook.ems.model.entity.EmsBomContact;
import com.dynabook.ems.model.entity.EmsBomDetail;
import com.dynabook.ems.model.entity.EmsWorkOrder;
import com.dynabook.ems.model.entity.EmsWorkOrderDetail;
import com.dynabook.ems.model.enums.DetailStatusEnum;
import com.dynabook.ems.model.enums.WorkOrderStatusEnum;
import com.dynabook.ems.model.vo.WorkOrderBomDetailVO;
import com.dynabook.ems.model.vo.WorkOrderBomSimpleVO;
import com.dynabook.ems.service.EmsBomDetailService;
import com.dynabook.ems.service.EmsWorkOrderDetailService;
import com.dynabook.ems.service.EmsWorkOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author tester
 * @description 针对表【ems_bom_detail】的数据库操作Service实现
 * @createDate 2025-07-21 15:20:05
 */
@Service
@Slf4j
public class EmsBomDetailServiceImpl extends ServiceImpl<EmsBomDetailMapper, EmsBomDetail>
        implements EmsBomDetailService {
    @Resource
    private EmsBomDetailMapper emsBomDetailMapper;
    @Resource
    private EmsBomContactMapper emsBomContactMapper;
    @Resource
    @Lazy
    private EmsWorkOrderService emsWorkOrderService;

    @Resource
    @Lazy
    private EmsWorkOrderDetailService emsWorkOrderDetailService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Boolean> deleteBomDetailById(Long detailId) {
        try {
            // 参数验证
            if (detailId == null) {
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "detailId不能为空");
            }

            // 检查BOM详情是否存在
            EmsBomDetail bomDetail = emsBomDetailMapper.selectById(detailId);
            if (bomDetail == null) {
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "BOM详情不存在");
            }

            // 删除关联的ems_bom_contact记录
            LambdaQueryWrapper<EmsBomContact> contactWrapper = new LambdaQueryWrapper<>();
            contactWrapper.eq(EmsBomContact::getBomDetailId, detailId);
            emsBomContactMapper.delete(contactWrapper);

            // 删除ems_bom_detail记录
            int deleteResult = emsBomDetailMapper.deleteById(detailId);
            if (deleteResult <= 0) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除BOM详情失败: " + detailId);
            }

            log.info("成功删除BOM详情，ID: {}", detailId);
            return ResultUtils.success(true);

        } catch (BusinessException e) {
            log.error("删除BOM详情失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("删除BOM详情时发生异常，ID: {}", detailId, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除BOM详情失败: " + detailId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Boolean> updateDetailStatusByWorkOrder(String workOrderNumber,Integer totalNumber) {
        try {
            // 参数验证
            if (StrUtil.isBlank(workOrderNumber)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "工单号不能为空");
            }

            // 查询该工单下的所有BOM详情记录
            LambdaQueryWrapper<EmsWorkOrderDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber)
                    .eq(EmsWorkOrderDetail::getIsDelete, 0);

            List<EmsWorkOrderDetail> bomDetailList = emsWorkOrderDetailService.list(queryWrapper);

            if (bomDetailList.isEmpty()) {
                log.info("工单号 {} 下没有找到相关的BOM详情记录", workOrderNumber);
                return ResultUtils.success(true);
            }

            // 批量更新detail_status为BEFORE_SELECTED
            LambdaUpdateWrapper<EmsWorkOrderDetail> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber)
                    .eq(EmsWorkOrderDetail::getIsDelete, 0)
                    .eq(EmsWorkOrderDetail::getModelCategory, "P")
                    .set(EmsWorkOrderDetail::getDetailStatus, DetailStatusEnum.BEFORE_SELECTED.getValue())
                    .set(EmsWorkOrderDetail::getTotalNum, totalNumber)
                    .set(EmsWorkOrderDetail::getUpdateTime, LocalDateTime.now());
            boolean updateResult = emsWorkOrderDetailService.update(updateWrapper);
            
            // 检查是否存在改造品记录
            LambdaQueryWrapper<EmsWorkOrderDetail> checkChangeWrapper = new LambdaQueryWrapper<>();
            checkChangeWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber)
                    .eq(EmsWorkOrderDetail::getIsDelete, 0)
                    .eq(EmsWorkOrderDetail::getModelCategory, "D");
            long changeCount = emsWorkOrderDetailService.count(checkChangeWrapper);
            
            boolean changeResult = true; // 默认为true，如果没有改造品记录就不需要更新
            if (changeCount > 0) {
                // 改造品 更新数量
                LambdaUpdateWrapper<EmsWorkOrderDetail> changeUpdateWrapper = new LambdaUpdateWrapper<>();
                changeUpdateWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber)
                        .eq(EmsWorkOrderDetail::getIsDelete, 0)
                        .eq(EmsWorkOrderDetail::getModelCategory, "D")
                        .set(EmsWorkOrderDetail::getTotalNum, totalNumber)
                        .set(EmsWorkOrderDetail::getUpdateTime, LocalDateTime.now());
                changeResult = emsWorkOrderDetailService.update(changeUpdateWrapper);
                log.info("工单号 {} 存在 {} 条改造品记录，更新结果: {}", workOrderNumber, changeCount, changeResult);
            } else {
                log.info("工单号 {} 不存在改造品记录，跳过改造品更新", workOrderNumber);
            }
            
            if (updateResult && changeResult) {
                log.info("成功更新工单号 {} 下的 {} 条BOM详情记录状态为待选状态", workOrderNumber, bomDetailList.size());
                return ResultUtils.success(true);
            } else {
                log.error("更新工单号 {} 下的BOM详情状态失败", workOrderNumber);
                throw  new BusinessException(ErrorCode.SYSTEM_ERROR, "更新BOM详情状态失败 ");
            }

        } catch (Exception e) {
            log.error("更新工单号 {} 下的BOM详情状态失败", workOrderNumber);
            throw  new BusinessException(ErrorCode.SYSTEM_ERROR, "更新BOM详情状态失败 "+e.getMessage());
        }
    }

    @Override
    public BaseResponse<WorkOrderBomDetailVO> getBomDetailByWorkOrderNumber(WorkOrderBomDetailRequest request) {
        try {
            // 参数验证
            if (StrUtil.isBlank(request.getWorkOrderNumber())) {
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "工单号不能为空");
            }

            // 1. 查询BOM基本信息
            WorkOrderBomDetailVO bomDetailVO = this.baseMapper.getBomBasicInfoByWorkOrderNumber(request.getWorkOrderNumber());

            if (bomDetailVO == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到该工单下的BOM信息");
            }

            // 2. 查询工单状态，判断是否可编辑
            LambdaQueryWrapper<EmsWorkOrder> workOrderWrapper = new LambdaQueryWrapper<>();
            workOrderWrapper.eq(EmsWorkOrder::getWorkOrderNum, request.getWorkOrderNumber())
                           .eq(EmsWorkOrder::getIsDelete, 0);
            EmsWorkOrder workOrder = emsWorkOrderService.getOne(workOrderWrapper);
            
            // 使用Optional处理可能的null值
            boolean canEdit = Optional.ofNullable(workOrder)
                .map(EmsWorkOrder::getWorkOrderStatus)
                .map(status -> WorkOrderStatusEnum.MODIFIED.getValue().equals(status) || 
                               WorkOrderStatusEnum.PENDING.getValue().equals(status) ||WorkOrderStatusEnum.INSTOCK.getValue().equals(status))
                .orElse(false);
            
            Integer productionQuantity = Optional.ofNullable(workOrder)
                .map(EmsWorkOrder::getProductionQuantity)
                .orElse(null);
            
            bomDetailVO.setCanEdit(canEdit);
            bomDetailVO.setProductionQuantity(productionQuantity);
            log.info("工单号: {}, 工单状态: {}, 是否可编辑: {}, 生产数量: {}", 
                    request.getWorkOrderNumber(), 
                    workOrder != null ? workOrder.getWorkOrderStatus() : "未找到", 
                    canEdit,
                    productionQuantity);

            // 3. 分页查询BOM详情列表
            Page<WorkOrderBomDetailVO.WorkOrderBomDetailItem> page = new Page<>(request.getCurrent(), request.getPageSize());
            Page<WorkOrderBomDetailVO.WorkOrderBomDetailItem> bomDetailPage = this.baseMapper.pageBomDetailByWorkOrderNumber(page, request.getWorkOrderNumber());

            // 4. 设置分页数据
            bomDetailVO.setBomDetails(bomDetailPage);

            return ResultUtils.success(bomDetailVO);

        } catch (Exception e) {
            log.error("根据工单号分页查询BOM详细信息失败，工单号: {}", request.getWorkOrderNumber(), e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询BOM详细信息失败");
        }
    }

    @Override
    public BaseResponse<WorkOrderBomSimpleVO> getBomSimpleDetailByWorkOrderNumber(WorkOrderBomSimpleRequest request) {
        try {
            String workOrderNumber = request.getWorkOrderNumber();
            log.info("开始查询工单号 {} 的BOM简化详情", workOrderNumber);
            // 1. 查询BOM基本信息
            WorkOrderBomDetailVO bomDetailVO = this.baseMapper.getBomBasicInfoByWorkOrderNumber(request.getWorkOrderNumber());
            WorkOrderBomSimpleVO result = new WorkOrderBomSimpleVO();
            if (bomDetailVO == null) {
                return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到该工单下的BOM信息");
            }

            // 2. 查询工单状态，判断是否可编辑
            LambdaQueryWrapper<EmsWorkOrder> workOrderWrapper = new LambdaQueryWrapper<>();
            workOrderWrapper.eq(EmsWorkOrder::getWorkOrderNum, request.getWorkOrderNumber())
                    .eq(EmsWorkOrder::getIsDelete, 0);
            EmsWorkOrder workOrder = emsWorkOrderService.getOne(workOrderWrapper);

            // 使用Optional处理可能的null值
            boolean canEdit = Optional.ofNullable(workOrder)
                    .map(EmsWorkOrder::getWorkOrderStatus)
                    .map(status -> WorkOrderStatusEnum.MODIFIED.getValue().equals(status) ||
                            WorkOrderStatusEnum.PENDING.getValue().equals(status) ||  WorkOrderStatusEnum.INSTOCK.getValue().equals(status))
                    .orElse(false);

            Integer productionQuantity = Optional.ofNullable(workOrder)
                    .map(EmsWorkOrder::getProductionQuantity)
                    .orElse(null);
            result.setCanEdit(canEdit);
            result.setProductionQuantity(productionQuantity);
            result.setProductName(bomDetailVO.getProductName());
            result.setFinishProductName(bomDetailVO.getFinishProductName());
            result.setMachineName(bomDetailVO.getMachineName());
            result.setVersion(bomDetailVO.getVersion());
            log.info("工单号: {}, 工单状态: {}, 是否可编辑: {}, 生产数量: {}",
                    request.getWorkOrderNumber(),
                    workOrder != null ? workOrder.getWorkOrderStatus() : "未找到",
                    canEdit,
                    productionQuantity);
            
            // 直接根据工单号查询BOM详情项
            LambdaQueryWrapper<EmsWorkOrderDetail> detailWrapper = new LambdaQueryWrapper<>();
            detailWrapper.eq(EmsWorkOrderDetail::getWorkOrderNumber, workOrderNumber)
                        .eq(EmsWorkOrderDetail::getIsDelete, 0)
                        .orderByAsc(EmsWorkOrderDetail::getId);
            List<EmsWorkOrderDetail> bomDetailList =  emsWorkOrderDetailService.list(detailWrapper);

            if (bomDetailList.isEmpty()) {
                log.warn("工单号 {} 下没有找到BOM详情项", workOrderNumber);
                return ResultUtils.error(ErrorCode.PARAMS_ERROR, "该工单下没有BOM详情项");
            }
            
            // 转换为简化VO
            List<WorkOrderBomSimpleVO.BomSimpleItem> simpleItems = bomDetailList.stream()
                    .map(detail -> {
                        WorkOrderBomSimpleVO.BomSimpleItem item = new WorkOrderBomSimpleVO.BomSimpleItem();
                        item.setId(detail.getId().toString());
                        item.setModelType(detail.getModelType());
                        item.setModelName(detail.getModelName());
                        item.setCategory(detail.getCategory());
                        item.setBomQuantity(detail.getModelNumber()); // 使用model_number作为BOM数量
                        item.setTotalNum(Integer.valueOf(detail.getTotalNum())); // totalNum是String类型，需要转换
                        item.setModelUnit(detail.getModelUnit());
                        item.setModelCategory(detail.getModelCategory());
                        item.setRemark(detail.getRemark());
                        // 根据DetailStatusEnum获取状态文本
                        item.setDetailStatus(DetailStatusEnum.getTextByValue(detail.getDetailStatus()));
                        return item;
                    })
                    .collect(Collectors.toList());
            

            result.setBomDetails(simpleItems);
            
            log.info("成功查询工单号 {} 的BOM简化详情，共 {} 条", workOrderNumber, simpleItems.size());
            return ResultUtils.success(result);
            
        } catch (Exception e) {
            log.error("查询工单BOM简化详情失败", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }


}




